/*
 * Close code, not for any kind of distribution
 * All right reserved by sowrov
 */

package com.banglaocr.basic;
import com.googlecode.javacv.jna.cxcore.CvSize;
import java.awt.Color;
import com.sun.jna.Pointer;
import com.googlecode.javacv.jna.cxcore.IplImage;
import com.googlecode.javacv.jna.highgui;
import static com.googlecode.javacv.jna.highgui.*;
import static com.googlecode.javacv.jna.cv.*;
/**
 *
 * @author admin
 */
public class ExperimentalMethods {
    private String originalImagePath="";
    private IplImage originalImage = null;
    private IplImage redMarkedImage = null;

    private IplImage tmpImage = null;

    public ExperimentalMethods() {}

    public ExperimentalMethods(String imagPath) {
        this.originalImagePath = imagPath;

        this.originalImage = cvLoadImage(originalImagePath, -1);
    }

    /**
     * LoadType values:
     * CV_LOAD_IMAGE_UNCHANGED  = -1,
     * CV_LOAD_IMAGE_GRAYSCALE  = 0,
     * CV_LOAD_IMAGE_COLOR      = 1,
     * CV_LOAD_IMAGE_ANYDEPTH   = 2,
     * CV_LOAD_IMAGE_ANYCOLOR   = 4;
     */
    public void setImage(String imagePath, int loadType) {
        if (this.originalImage != null) {
            this.originalImage.release();
        }
        this.originalImagePath = imagePath;
        this.originalImage = cvLoadImage(originalImagePath, loadType);
    }

    public void setImage(String imagePath) {
        this.setImage(imagePath, highgui.CV_LOAD_IMAGE_UNCHANGED);
    }

    public void showInfo() {
        if (this.originalImage==null) {
            System.out.println("Couldn't find the image");
            return ;
        }

        System.out.println("Size - width: "+this.originalImage.width +
                " height: "+this.originalImage.height +
                " widthstep: "+this.originalImage.widthStep+
                " channel: "+this.originalImage.nChannels +
                " depth: "+this.originalImage.depth +
                " dataOrder: "+this.originalImage.dataOrder +
                " nSize: " + this.originalImage.nSize);
    }

    /**
     *
     *
     * @param imagePath where the image will be saved
     */
    public void edgeDetection(String imagePath) {
        //p1: if no original image then leave
        //p2: if original image is color image then make it gray
        //p1: find the canny image i.e. the edge marked image
        //p1: save the image in given path
        if (this.originalImage == null) {
            System.err.println("No image loaded");
            return;
        }

        if (this.tmpImage != null) {
            this.tmpImage.release();
        }
        this.tmpImage = IplImage.createFrom(this.originalImage.getBufferedImage());
        cvCanny(this.tmpImage, this.tmpImage, 10, 100, 3);
//            cvSobel(this.cannyImage, this.cannyImage, 0, 1, 3);
        cvSaveImage(imagePath, this.tmpImage);
    }

    public void inverseBlackAndWhite(String pathName) {
        if (this.originalImage==null) {
            System.err.println("No image found");
            return ;
        }

        this.tmpImage = IplImage.create(this.originalImage.getCvSize(), 8, 1); //black and white;
        int width = this.originalImage.width;
        int height = this.originalImage.height;
        int channels   = this.originalImage.nChannels;
        int step = this.originalImage.widthStep;
        Pointer data = this.originalImage.imageData;

        System.out.println(width+" "+height+" "+channels+" "+step);

        int stepr = this.tmpImage.widthStep;
        int channelsr = this.tmpImage.nChannels;
        Pointer datar = this.tmpImage.imageData;

        for (int i= 0; i < height; i++) {
            for (int j= 0; j < width; j++) {
                int blui = 0x000000FF & data.getInt(i*step+j*(channels));
                int grni = 0x000000FF &data.getInt(i*step+j*(channels)+1);
                int redi= 0x000000FF & data.getInt(i*step+j*(channels)+2);
                if (redi<=50 && grni<=50 && blui<=50) {
                    datar.setChar((long)i*stepr+j*channelsr, (char)255);
                } else {
                    datar.setChar((long)i*stepr+j*channelsr, (char)0);
                }
            }
        }
        cvSaveImage(pathName+"_", this.originalImage);
        cvSaveImage(pathName, this.tmpImage);
    }

    public void filterColor(String pathName, Color color) {
        if (this.originalImage==null) {
            System.err.println("No image found");
            return ;
        }

        if (this.redMarkedImage==null) {
            this.redMarkedImage = IplImage.create(this.originalImage.getCvSize(), 8, 1);
            int width = this.originalImage.width;
            int height = this.originalImage.height;
            int channels   = this.originalImage.nChannels;
            int step = this.originalImage.widthStep;
            Pointer data = this.originalImage.imageData;

            System.out.println(width+" "+height+" "+channels+" "+step);

            int stepr = this.redMarkedImage.widthStep;
            int channelsr = this.redMarkedImage.nChannels;
            Pointer datar = this.redMarkedImage.imageData;
            int threshold = 30;
            for (int i= 0; i < height; i++) {
                for (int j= 0; j < width; j++) {
                    int blui = 0x000000FF & data.getInt(i*step+j*(channels));
                    int grni = 0x000000FF &data.getInt(i*step+j*(channels)+1);
                    int redi= 0x000000FF & data.getInt(i*step+j*(channels)+2);
//                    System.out.print("("+redi+","+grni+","+blui+")");
                    
//                    System.out.print("("+rI+","+gI+","+bI+")");
                    if ((color == Color.RED && redi>grni+threshold && redi>blui+threshold)
                            || (color == Color.BLUE && blui>grni+threshold && blui>redi+threshold)
                            || (color == Color.GREEN && grni>blui+threshold && grni>redi+threshold)) {
//                    if (255-redi < constVal  && grni < constVal && blui < constVal) {
                        datar.setChar((long)i*stepr+j*channelsr, (char)255);
                    } else {
                        datar.setChar((long)i*stepr+j*channelsr, (char)0);
                    }
                }
                System.out.println("");
            }
        }

        cvSaveImage(pathName, this.redMarkedImage);
        
    }
}
